package co.recloud.ariadne.thread;

import java.io.IOException;
import java.net.ServerSocket;

import co.recloud.ariadne.store.HostTable;

public class Main extends Thread {
	public static final int STATUS_STANDBY = 1;
	public static final int STATUS_SERVICE_PENDING = 2;
	public static final int STATUS_SERVICE = 3;
	public static final int STATUS_RECOVERY_PENDING = 4;
	public static final int STATUS_RECOVERY = 5;
	public static final int STATUS_MIGRATE = 6;
	
	private static int currentStatus;
	private static Long time;
	
	public static Long getTime() {
		if(time == null) {
			time = 1L;
		} else {
			time++;
		}
		return time;
	}
	
	public static void setTime(Long time) {
		if(Main.time == null) {
			Main.time = 1L;
		}
		if(time != null && time > Main.time){
			Main.time = time + 1;
		} else {
			Main.time++;
		}
	}
	
	public static void main(String[] args) {
		currentStatus = STATUS_STANDBY;
		try {
			
			String localHostName = "127.0.0.1";
			int apiPort = 50000;
			int dataPort = 50001;
			if(args.length > 0) {
				localHostName = args[args.length - 3];
			}
			if(args.length > 1) {
				apiPort = Integer.parseInt(args[args.length - 2]);
			}
			if(args.length > 2) {
				dataPort = Integer.parseInt(args[args.length - 1]);
			}
			HostTable ht = HostTable.getInstance();
			ht.setLocalhost(localHostName, dataPort);
			System.out.println(ht.getTokenRing());
			ServerSocket apiSocket = new ServerSocket(apiPort);
			ServerSocket dataSocket = new ServerSocket(dataPort);

			Runnable apiListener = new APIThread(apiSocket);
			Runnable dataListener = new DataThread(dataSocket);
			Runnable partitioner = new PartitionerThread();
			Runnable condenser = new CondenserThread();
			ThreadPool.startThread(apiListener);
			ThreadPool.startThread(dataListener);
			ThreadPool.startThread(partitioner);
			ThreadPool.startThread(condenser);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public static void setCurrentStatus(int status) {
		currentStatus = status;
	}
	
	public static int getCurrentStatus() {
		return currentStatus;
	}

	public static boolean waitForServiceStatus() {
		if(Main.getCurrentStatus() != Main.STATUS_SERVICE) {
			Object lock = new Object();
			synchronized (lock) {
				try {
					lock.wait(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return false;
		}		
		return true;
	}

	public static boolean waitForIdle() {
		Long time1 = Main.getTime();
		Long time2 = Main.getTime();
		Object lock = new Object();
		if(time2 - time1 > 1) {
			synchronized (lock) {
				try {
					lock.wait(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return false;
		}
		return true;
	}
}
